package com.jwgf.smarowindingmachine_unity.ui;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.Spinner;
import android.widget.TextView;

import com.jwgf.common.ViewCache;
import com.jwgf.objectbox.CbfReport;
import com.jwgf.objectbox.ObjectBox;
import com.jwgf.objectbox.ShiftReport;
import com.jwgf.objectbox.StatisticRecord;
import com.jwgf.objectbox.TubeRecord;
import com.jwgf.objectbox.UserLogin;
import com.jwgf.report.ShiftTimeRule;
import com.jwgf.smarowindingmachine_unity.R;
import com.jwgf.smarowindingmachine_unity.logic.MachineParameterSharedPreference;
import com.jwgf.smarowindingmachine_unity.logic.Report;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.objectbox.Box;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.functions.Function;
import io.reactivex.rxjava3.schedulers.Schedulers;


public class ProductionManagementShiftReportFragmentRx extends BaseFragment {
    private View v;
    private RelativeLayout content_relativelayout;
    private ProductionGeneralView generalView;
    private ProductionSpindleView production_data_view;
    private ProductionStatisticViewG statistic_time_view;
    private ProductionBadSpindleAnalysisView bad_spindle_view;
    private ProductionTubeMonitorView tube_monitor_view;
    private ProductionCBFView cbf_view;
    private ProductionDofferView doffer_view;


    private TextView date;
    private TextView shift_num;
    private Spinner operator_spinner;
    private TextView operator_tv;
    private TextView shift_team_tv;
    private Spinner shift_team_spinner;
    private TextView running_time_tv;
    private Button head_btn;
    private Button prev_btn;
    private Button next_btn;
    private Button tail_btn;
    private TextView tvShiftInfoShow;
    private long totalRecord;
    private long currentRecord;

    private Button general_tab;
    private Button production_data_tab;
    private Button stat_time_tab;
    private Button bad_spindle_tab;
    private Button tube_monitor_tab;
    private Button cbf_tab;
    private Button doffer_tab;
    private ImageButton upload_cloud_btn;

    private Calendar curDate = Calendar.getInstance();

    private ArrayAdapter<String> shiftTeamAdapter;
    private ArrayList<String> shiftTeamList = new ArrayList<String>();
    private ArrayAdapter<String> operatorAdapter;
    private ArrayList<String> operatorList = new ArrayList<String>();

    // report type
    private int reportType = Report_Type.general;

    private boolean[] buttonStatus = {true, true, false, true};

    private Disposable disposable;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        v = ViewCache.getInstance().getView(R.layout.fragment_production_management_shift_report);
        content_relativelayout = (RelativeLayout) v.findViewById(R.id.duty_layout);

        initViews();
        general_tab.callOnClick();

        disposable = Observable.interval(1, TimeUnit.MINUTES).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Long>() {
            @Override
            public void accept(Long aLong) throws Exception {
                refreshContent(reportType, "=");
            }
        });
        return v;
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (hidden) {
            disposable.dispose();
        } else {
            refreshCBFDofferTab();
            refreshContent(reportType, "=");
            disposable = Observable.interval(1, TimeUnit.MINUTES).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    refreshContent(reportType, "=");
                }
            });
        }
    }

    private void initViews() {
        date = (TextView) v.findViewById(R.id.date);
        shift_num = (TextView) v.findViewById(R.id.shift_num);
        operator_spinner = (Spinner) v.findViewById(R.id.operator_spinner);
        operator_tv = (TextView) v.findViewById(R.id.operator_tv);
        shift_team_tv = (TextView) v.findViewById(R.id.shiftteam_tv);
        running_time_tv = v.findViewById(R.id.running_time_tv);
        currentRecord = Report.getInstance().getShiftCount();
        totalRecord = Report.getInstance().getShiftCount();

        shift_team_spinner = (Spinner) v.findViewById(R.id.shiftteam_spinner);
        head_btn = (Button) v.findViewById(R.id.head_btn);
        prev_btn = (Button) v.findViewById(R.id.prev_btn);
        next_btn = (Button) v.findViewById(R.id.next_btn);
        tail_btn = (Button) v.findViewById(R.id.tail_btn);
        upload_cloud_btn = v.findViewById(R.id.upload_cloud_btn);
        tvShiftInfoShow = (TextView) v.findViewById(R.id.tv_shift_show);

        OnClickListener tabListener = new OnClickListener() {
            @Override
            public void onClick(View v) {
                switchTabBackground(v.getId());
                switch (reportType) {
                    case Report_Type.productData:
                    case Report_Type.statisticsTime:
                    case Report_Type.badSpindle:
                    case Report_Type.tube:
                    case Report_Type.cbf:
                    case Report_Type.doffer:
                    case Report_Type.general:
                        refreshContent(reportType, "=");
                        break;

                }
            }
        };
        // btn
        production_data_tab = (Button) v.findViewById(R.id.production_data_tab);
        production_data_tab.setOnClickListener(tabListener);

        stat_time_tab = (Button) v.findViewById(R.id.stat_time_tab);
        stat_time_tab.setOnClickListener(tabListener);

        bad_spindle_tab = (Button) v.findViewById(R.id.bad_spindle_tab);
        bad_spindle_tab.setOnClickListener(tabListener);

        tube_monitor_tab = (Button) v.findViewById(R.id.tube_monitor_tab);
        tube_monitor_tab.setOnClickListener(tabListener);

        cbf_tab = (Button) v.findViewById(R.id.CBF_tab);
        cbf_tab.setOnClickListener(tabListener);

        doffer_tab = (Button) v.findViewById(R.id.doffer_tab);
        doffer_tab.setOnClickListener(tabListener);

        general_tab = v.findViewById(R.id.general_tab);
        general_tab.setOnClickListener(tabListener);

        head_btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                refreshContent(reportType, "<<");
            }
        });

        prev_btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                refreshContent(reportType, "<");
            }
        });

        next_btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                refreshContent(reportType, ">");
            }
        });

        tail_btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                refreshContent(reportType, ">>");
            }
        });

        upload_cloud_btn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                QRCodeGalleryDialog dlg = new QRCodeGalleryDialog();
                dlg.show(getFragmentManager(), "qr_report_dlg");
            }
        });

        shiftTeamList.clear();
        String[] shiftTeams = getActivity().getResources().getStringArray(R.array.shift_team);
        for (int i = 0; i < shiftTeams.length; i++) {
            shiftTeamList.add(shiftTeams[i]);
        }
        shift_team_spinner.setAdapter(shiftTeamAdapter = new ArrayAdapter<String>(getActivity(),
                android.R.layout.simple_dropdown_item_1line, shiftTeamList));
        String shiftTeam = ShiftTimeRule.getInstance().getShiftTeam();
        int indexShiftTeam = shiftTeamList.indexOf(shiftTeam);
        if (indexShiftTeam != -1) {
            shift_team_spinner.setSelection(indexShiftTeam);
        }
        shift_team_spinner.setOnItemSelectedListener(new OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                TextView tv = (TextView) view;
                if (tv != null)
                    tv.setTextSize(10.0f);
                ShiftTimeRule.getInstance().setShiftTeam(shiftTeamList.get(position));
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

        operator_spinner.setAdapter(operatorAdapter = new ArrayAdapter<String>(getActivity(),
                android.R.layout.simple_dropdown_item_1line, getOperatorData()));
        String operator = ShiftTimeRule.getInstance().getOperator();
        int index = operatorList.indexOf(operator);
        if (index != -1) {
            operator_spinner.setSelection(index);
        }
        operator_spinner.setOnItemSelectedListener(new OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                TextView tv = (TextView) view;
                if (tv != null)
                    tv.setTextSize(10.0f);
                ShiftTimeRule.getInstance().setOperator(operatorList.get(position));
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

        refreshCBFDofferTab();

    }

    private void refreshCBFDofferTab() {
        if (MachineParameterSharedPreference.getInstance()
                .getValue(MachineParameterSharedPreference.MACHINE_MACHINE_TYPE, "0").equals("0")) {
            cbf_tab.setEnabled(false);
            cbf_tab.setTextColor(getResources().getColor(R.color.disable));
            doffer_tab.setEnabled(false);
            doffer_tab.setTextColor(getResources().getColor(R.color.disable));
        } else if (MachineParameterSharedPreference.getInstance()
                .getValue(MachineParameterSharedPreference.MACHINE_MACHINE_TYPE, "0").equals("1")) {
            cbf_tab.setEnabled(false);
            cbf_tab.setTextColor(getResources().getColor(R.color.disable));
            doffer_tab.setEnabled(true);
            doffer_tab.setTextColor(getResources().getColor(R.color.text_color_selector));
            if (reportType == Report_Type.doffer) {
                doffer_tab.setSelected(true);
            } else {
                doffer_tab.setSelected(false);
            }
        } else if (MachineParameterSharedPreference.getInstance()
                .getValue(MachineParameterSharedPreference.MACHINE_MACHINE_TYPE, "0").equals("4")) {
            cbf_tab.setEnabled(false);
            cbf_tab.setTextColor(getResources().getColor(R.color.disable));
            doffer_tab.setEnabled(true);
            doffer_tab.setTextColor(getResources().getColor(R.color.text_color_selector));
            if (reportType == Report_Type.doffer) {
                doffer_tab.setSelected(true);
            } else {
                doffer_tab.setSelected(false);
            }
        } else if (MachineParameterSharedPreference.getInstance()
                .getValue(MachineParameterSharedPreference.MACHINE_MACHINE_TYPE, "0").equals("3")
                || MachineParameterSharedPreference.getInstance()
                .getValue(MachineParameterSharedPreference.MACHINE_MACHINE_TYPE, "0").equals("5")) {

            cbf_tab.setEnabled(true);
            doffer_tab.setEnabled(true);
            cbf_tab.setTextColor(getResources().getColor(R.color.text_color_selector));
            if (reportType == Report_Type.cbf) {
                cbf_tab.setSelected(true);
            } else {
                cbf_tab.setSelected(false);
            }
            doffer_tab.setTextColor(getResources().getColor(R.color.text_color_selector));
            if (reportType == Report_Type.doffer) {
                doffer_tab.setSelected(true);
            } else {
                doffer_tab.setSelected(false);
            }
        }
        int isYes = Integer.parseInt(MachineParameterSharedPreference.getInstance()
                .getValue(MachineParameterSharedPreference.BAD_SPINDLE, "0"));
        if (isYes == 0) {
            bad_spindle_tab.setVisibility(View.GONE);
        } else {
            bad_spindle_tab.setVisibility(View.VISIBLE);
        }

    }

    private List<String> getOperatorData() {
        operatorList.clear();
        Box<UserLogin> box = ObjectBox.get().boxFor(UserLogin.class);
        List<UserLogin> list = box.getAll();
        for (UserLogin user : list) {
            operatorList.add(user.user);
        }
        return operatorList;
    }

    private void refreshBasicUI(ShiftReport shiftReport) {
        curDate.setTimeInMillis(shiftReport.start);
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String strDate = sf.format(curDate.getTime());
        String num = String.valueOf(shiftReport.shiftNum);
        String strOperator = shiftReport.operator;
        String strShiftTeam = shiftReport.team;
        long runningTime = Report.getInstance().getHeadReport(shiftReport.start).runningTime;
        String strRunningTime = getString(R.string.running_time) + " "
                + Report.getInstance().subSecToTime(runningTime / 1000);
        if (currentRecord == 1) {
            buttonStatus[0] = true;
            buttonStatus[1] = false;
            buttonStatus[2] = true;
            buttonStatus[3] = true;
        } else if (currentRecord == totalRecord) {
            buttonStatus[0] = true;
            buttonStatus[1] = true;
            buttonStatus[2] = false;
            buttonStatus[3] = true;
        } else {
            buttonStatus[0] = true;
            buttonStatus[1] = true;
            buttonStatus[2] = true;
            buttonStatus[3] = true;
        }
        date.setText(strDate);
        shift_num.setText(num);
        shift_team_tv.setText(strShiftTeam);
        operator_tv.setText(strOperator);
        running_time_tv.setText(strRunningTime);
        tvShiftInfoShow.setText(currentRecord + "/" + totalRecord);
        long curStart = Long.valueOf(ShiftTimeRule.getInstance().getCurrentShiftStartTime());
        if (curDate.getTimeInMillis() == curStart) {
            operator_spinner.setVisibility(View.VISIBLE);
            operator_tv.setVisibility(View.INVISIBLE);
            shift_team_spinner.setVisibility(View.VISIBLE);
            shift_team_tv.setVisibility(View.INVISIBLE);
            upload_cloud_btn.setVisibility(View.INVISIBLE);
        } else {
            operator_spinner.setVisibility(View.INVISIBLE);
            operator_tv.setVisibility(View.VISIBLE);
            shift_team_spinner.setVisibility(View.INVISIBLE);
            shift_team_tv.setVisibility(View.VISIBLE);
            upload_cloud_btn.setVisibility(View.INVISIBLE);
        }
    }

    private void setBtnState(boolean isEnable) {
        if (isEnable) {
            head_btn.setEnabled(buttonStatus[0]);
            prev_btn.setEnabled(buttonStatus[1]);
            next_btn.setEnabled(buttonStatus[2]);
            tail_btn.setEnabled(buttonStatus[3]);
        } else {
            head_btn.setEnabled(false);
            prev_btn.setEnabled(false);
            next_btn.setEnabled(false);
            tail_btn.setEnabled(false);
        }

    }

    private void refreshContent(int reportType, String flag) {
        switch (reportType) {
            case Report_Type.general:
                rxGeneral(curDate.getTimeInMillis(), flag);
                break;
            case Report_Type.productData:
                rxProduction(curDate.getTimeInMillis(), flag);
                break;
            case Report_Type.statisticsTime:
                rxStatistic(curDate.getTimeInMillis(), flag);
                break;
            case Report_Type.badSpindle:
                rxBadSpindle(curDate.getTimeInMillis(), flag);
                break;
            case Report_Type.tube:
                rxTubeMonitor(curDate.getTimeInMillis(), flag);
                break;
            case Report_Type.cbf:
                rxCBF(curDate.getTimeInMillis(), flag);
                break;
            case Report_Type.doffer:
                rxDoffer(curDate.getTimeInMillis(), flag);
                break;
            default:
                break;
        }
    }

    private void showGeneralView() {
        content_relativelayout.removeAllViews();
        if (generalView == null) {
            generalView = new ProductionGeneralView(getActivity());
        }
        content_relativelayout.addView(generalView);
    }

    private void showDutyProductionData(List<ShiftReport> production) {
        content_relativelayout.removeAllViews();
        if (production_data_view == null) {
            production_data_view = new ProductionSpindleView(getActivity());
        }
        content_relativelayout.addView(production_data_view);
        production_data_view.setData(production);
    }

    private void showStatisticTime(List<StatisticRecord> data) {
        content_relativelayout.removeAllViews();
        if (statistic_time_view == null) {
            statistic_time_view = new ProductionStatisticViewG(getActivity());
        }
        content_relativelayout.addView(statistic_time_view);
        statistic_time_view.setData(data);
    }

    private void showBadSpindleView() {
        content_relativelayout.removeAllViews();
        if (bad_spindle_view == null) {
            bad_spindle_view = new ProductionBadSpindleAnalysisView(getActivity());
        }
        content_relativelayout.addView(bad_spindle_view);
    }

    private void showTubeMonitor(List<TubeRecord> records) {
        content_relativelayout.removeAllViews();
        if (tube_monitor_view == null) {
            tube_monitor_view = new ProductionTubeMonitorView(getActivity());
        }
        content_relativelayout.addView(tube_monitor_view);
        tube_monitor_view.setData(records);
    }

    private void showDutyReportCBF(CbfReport cbfReport) {
        content_relativelayout.removeAllViews();
        if (cbf_view == null) {
            cbf_view = new ProductionCBFView(getActivity());
        }
        content_relativelayout.addView(cbf_view);
        cbf_view.setData(cbfReport);
    }

    private void showDutyReportDoffer(CbfReport cbfReport) {
        content_relativelayout.removeAllViews();
        if (doffer_view == null) {
            doffer_view = new ProductionDofferView(getActivity());
        }
        content_relativelayout.addView(doffer_view);
        doffer_view.setData(cbfReport);
    }

    private void switchTabBackground(int id) {

        switch (id) {
            case R.id.production_data_tab: {
                reportType = Report_Type.productData;
                production_data_tab.setSelected(true);
                stat_time_tab.setSelected(false);
                bad_spindle_tab.setSelected(false);
                tube_monitor_tab.setSelected(false);
                cbf_tab.setSelected(false);
                doffer_tab.setSelected(false);
                general_tab.setSelected(false);
            }
            break;
            case R.id.stat_time_tab: {
                reportType = Report_Type.statisticsTime;
                production_data_tab.setSelected(false);
                stat_time_tab.setSelected(true);
                bad_spindle_tab.setSelected(false);
                tube_monitor_tab.setSelected(false);
                cbf_tab.setSelected(false);
                doffer_tab.setSelected(false);
                general_tab.setSelected(false);
            }
            break;
            case R.id.bad_spindle_tab: {
                reportType = Report_Type.badSpindle;
                production_data_tab.setSelected(false);
                stat_time_tab.setSelected(false);
                tube_monitor_tab.setSelected(false);
                bad_spindle_tab.setSelected(true);
                cbf_tab.setSelected(false);
                doffer_tab.setSelected(false);
                general_tab.setSelected(false);
            }
            break;
            case R.id.tube_monitor_tab: {
                reportType = Report_Type.tube;
                production_data_tab.setSelected(false);
                stat_time_tab.setSelected(false);
                tube_monitor_tab.setSelected(true);
                bad_spindle_tab.setSelected(false);
                cbf_tab.setSelected(false);
                doffer_tab.setSelected(false);
                general_tab.setSelected(false);
            }
            break;
            case R.id.CBF_tab: {
                reportType = Report_Type.cbf;
                production_data_tab.setSelected(false);
                stat_time_tab.setSelected(false);
                tube_monitor_tab.setSelected(false);
                bad_spindle_tab.setSelected(false);
                cbf_tab.setSelected(true);
                doffer_tab.setSelected(false);
                general_tab.setSelected(false);
            }
            break;
            case R.id.doffer_tab: {
                reportType = Report_Type.doffer;
                production_data_tab.setSelected(false);
                stat_time_tab.setSelected(false);
                tube_monitor_tab.setSelected(false);
                bad_spindle_tab.setSelected(false);
                cbf_tab.setSelected(false);
                doffer_tab.setSelected(true);
                general_tab.setSelected(false);
            }
            break;
            case R.id.general_tab: {
                reportType = Report_Type.general;
                production_data_tab.setSelected(false);
                stat_time_tab.setSelected(false);
                tube_monitor_tab.setSelected(false);
                bad_spindle_tab.setSelected(false);
                cbf_tab.setSelected(false);
                doffer_tab.setSelected(false);
                general_tab.setSelected(true);
            }
            break;
            default:
                break;
        }
    }

    public interface Report_Type {
        int productData = 0;
        int statisticsTime = 1;
        int badSpindle = 2;
        int cbf = 3;
        int doffer = 4;
        int tube = 5;
        int general = 6;
    }

    private void rxGeneral(long time, String flag) {
        setBtnState(false);
        Observable<Long> observable = Observable.create((ObservableOnSubscribe<ShiftReport>) emitter -> {
            long sqlTime = Report.getInstance().getTime(time, flag);
            ShiftReport basicInfo = Report.getInstance().getBasicInfo(sqlTime);
            totalRecord = Report.getInstance().getShiftCount();
            switch (flag) {
                case "<<":
                    currentRecord = 1;
                    break;
                case "<":
                    if (currentRecord > 1)
                        --currentRecord;
                    break;
                case ">":
                    if (currentRecord < totalRecord)
                        ++currentRecord;
                    break;
                case ">>":
                    currentRecord = totalRecord;
                    break;
            }
            emitter.onNext(basicInfo);
            emitter.onComplete();
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map((Function<ShiftReport, Long>) shiftReport -> {
                    refreshBasicUI(shiftReport);
                    showGeneralView();
                    return shiftReport.start;
                })
                .observeOn(Schedulers.io())
                .map((Function<Long, Long>) aLong -> {
                    generalView.loadData(aLong);
                    return aLong;
                })
                .observeOn(AndroidSchedulers.mainThread());

        Observer<Long> observer = new Observer<Long>() {
            Disposable d;

            @Override
            public void onSubscribe(Disposable d) {
                this.d = d;
            }

            @Override
            public void onNext(Long o) {
                generalView.setData();
                setBtnState(true);
            }

            @Override
            public void onError(Throwable e) {
                if (d != null && !d.isDisposed()) {
                    d.dispose();
                }
                try {
                    throw e;
                } catch (Throwable throwable) {
                    throwable.printStackTrace();
                }
            }

            @Override
            public void onComplete() {
                if (d != null && !d.isDisposed()) {
                    d.dispose();
                }
            }
        };
        observable.subscribe(observer);
    }

    private void rxProduction(long time, String flag) {
        setBtnState(false);
        Observable<List<ShiftReport>> observable = Observable.create((ObservableOnSubscribe<Long>) emitter -> {
            long sqlTime = Report.getInstance().getTime(time, flag);
            totalRecord = Report.getInstance().getShiftCount();
            switch (flag) {
                case "<<":
                    currentRecord = 1;
                    break;
                case "<":
                    if (currentRecord > 1)
                        --currentRecord;
                    break;
                case ">":
                    if (currentRecord < totalRecord)
                        ++currentRecord;
                    break;
                case ">>":
                    currentRecord = totalRecord;
                    break;
            }
            emitter.onNext(sqlTime);
            emitter.onComplete();
        })
                .map((Function<Long, List<ShiftReport>>) aLong -> {
                    List<ShiftReport> production = Report.getInstance().getProduction(aLong);
                    return production;
                })
                .subscribeOn(Schedulers.io())
                .doOnSubscribe(disposable -> setBtnState(false))
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread());

        Observer<List<ShiftReport>> observer = new Observer<List<ShiftReport>>() {
            Disposable d;

            @Override
            public void onSubscribe(Disposable d) {
                this.d = d;
            }

            @Override
            public void onNext(List<ShiftReport> shiftReports) {
                refreshBasicUI(shiftReports.get(0));
                showDutyProductionData(shiftReports);
                setBtnState(true);
            }

            @Override
            public void onError(Throwable e) {
                if (d != null && !d.isDisposed()) {
                    d.dispose();
                }
            }

            @Override
            public void onComplete() {
                if (d != null && !d.isDisposed()) {
                    d.dispose();
                }
            }
        };
        observable.subscribe(observer);
    }

    private void rxStatistic(long time, String flag) {
        setBtnState(false);
        Observable<List<StatisticRecord>> observable = Observable.create((ObservableOnSubscribe<ShiftReport>) emitter -> {
            long sqlTime = Report.getInstance().getTime(time, flag);
            ShiftReport basicInfo = Report.getInstance().getBasicInfo(sqlTime);
            totalRecord = Report.getInstance().getShiftCount();
            switch (flag) {
                case "<<":
                    currentRecord = 1;
                    break;
                case "<":
                    if (currentRecord > 1)
                        --currentRecord;
                    break;
                case ">":
                    if (currentRecord < totalRecord)
                        ++currentRecord;
                    break;
                case ">>":
                    currentRecord = totalRecord;
                    break;
            }
            emitter.onNext(basicInfo);
            emitter.onComplete();
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map((Function<ShiftReport, Long>) shiftReport -> {
                    refreshBasicUI(shiftReport);
                    return shiftReport.start;
                })
                .observeOn(Schedulers.io())
                .map((Function<Long, List<StatisticRecord>>) aLong -> {
                    long start = aLong;
                    List<StatisticRecord> data = Report.getInstance().getStatistic(start);
                    return data;
                })
                .observeOn(AndroidSchedulers.mainThread());

        Observer<List<StatisticRecord>> observer = new Observer<List<StatisticRecord>>() {
            Disposable d;

            @Override
            public void onSubscribe(Disposable d) {
                this.d = d;
            }

            @Override
            public void onNext(List<StatisticRecord> shiftReports) {
                showStatisticTime(shiftReports);
                setBtnState(true);
            }

            @Override
            public void onError(Throwable e) {
                if (d != null && !d.isDisposed()) {
                    d.dispose();
                }
            }

            @Override
            public void onComplete() {
                if (d != null && !d.isDisposed()) {
                    d.dispose();
                }
            }
        };
        observable.subscribe(observer);
    }

    private void rxBadSpindle(long time, String flag) {
        setBtnState(false);
        Observable<Long> observable = Observable.create((ObservableOnSubscribe<ShiftReport>) emitter -> {
            long sqlTime = Report.getInstance().getTime(time, flag);
            ShiftReport basicInfo = Report.getInstance().getBasicInfo(sqlTime);
            totalRecord = Report.getInstance().getShiftCount();
            switch (flag) {
                case "<<":
                    currentRecord = 1;
                    break;
                case "<":
                    if (currentRecord > 1)
                        --currentRecord;
                    break;
                case ">":
                    if (currentRecord < totalRecord)
                        ++currentRecord;
                    break;
                case ">>":
                    currentRecord = totalRecord;
                    break;
            }
            emitter.onNext(basicInfo);
            emitter.onComplete();
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map((Function<ShiftReport, Long>) shiftReport -> {
                    refreshBasicUI(shiftReport);
                    showBadSpindleView();
                    return shiftReport.start;
                })
                .observeOn(Schedulers.io())
                .map((Function<Long, Long>) aLong -> {
                    bad_spindle_view.loadData(aLong);
                    return aLong;
                })
                .observeOn(AndroidSchedulers.mainThread());

        Observer<Long> observer = new Observer<Long>() {
            Disposable d;

            @Override
            public void onSubscribe(Disposable d) {
                this.d = d;
            }

            @Override
            public void onNext(Long o) {
                bad_spindle_view.setData();
                setBtnState(true);
            }

            @Override
            public void onError(Throwable e) {
                if (d != null && !d.isDisposed()) {
                    d.dispose();
                }
                try {
                    throw e;
                } catch (Throwable throwable) {
                    throwable.printStackTrace();
                }
            }

            @Override
            public void onComplete() {
                if (d != null && !d.isDisposed()) {
                    d.dispose();
                }
            }
        };
        observable.subscribe(observer);
    }

    private void rxTubeMonitor(long time, String flag) {
        setBtnState(false);
        Observable<List<TubeRecord>> observable = Observable.create((ObservableOnSubscribe<ShiftReport>) emitter -> {
            long sqlTime = Report.getInstance().getTime(time, flag);
            ShiftReport basicInfo = Report.getInstance().getBasicInfo(sqlTime);
            totalRecord = Report.getInstance().getShiftCount();
            switch (flag) {
                case "<<":
                    currentRecord = 1;
                    break;
                case "<":
                    if (currentRecord > 1)
                        --currentRecord;
                    break;
                case ">":
                    if (currentRecord < totalRecord)
                        ++currentRecord;
                    break;
                case ">>":
                    currentRecord = totalRecord;
                    break;
            }
            emitter.onNext(basicInfo);
            emitter.onComplete();
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map((Function<ShiftReport, Long>) shiftReport -> {
                    refreshBasicUI(shiftReport);
                    return shiftReport.start;
                })
                .observeOn(Schedulers.io())
                .map((Function<Long, List<TubeRecord>>) aLong -> {
                    List<TubeRecord> data = Report.getInstance().getTubeMonitor(aLong);
                    ;
                    return data;
                })
                .observeOn(AndroidSchedulers.mainThread());

        Observer<List<TubeRecord>> observer = new Observer<List<TubeRecord>>() {
            Disposable d;

            @Override
            public void onSubscribe(Disposable d) {
                this.d = d;
            }

            @Override
            public void onNext(List<TubeRecord> records) {
                showTubeMonitor(records);
                setBtnState(true);
            }

            @Override
            public void onError(Throwable e) {
                if (d != null && !d.isDisposed()) {
                    d.dispose();
                }
            }

            @Override
            public void onComplete() {
                if (d != null && !d.isDisposed()) {
                    d.dispose();
                }
            }
        };
        observable.subscribe(observer);
    }

    private void rxCBF(long time, String flag) {
        setBtnState(false);
        Observable<CbfReport> observable = Observable.create((ObservableOnSubscribe<ShiftReport>) emitter -> {
            long sqlTime = Report.getInstance().getTime(time, flag);
            ShiftReport basicInfo = Report.getInstance().getBasicInfo(sqlTime);
            totalRecord = Report.getInstance().getShiftCount();
            switch (flag) {
                case "<<":
                    currentRecord = 1;
                    break;
                case "<":
                    if (currentRecord > 1)
                        --currentRecord;
                    break;
                case ">":
                    if (currentRecord < totalRecord)
                        ++currentRecord;
                    break;
                case ">>":
                    currentRecord = totalRecord;
                    break;
            }
            emitter.onNext(basicInfo);
            emitter.onComplete();
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map((Function<ShiftReport, Long>) shiftReport -> {
                    refreshBasicUI(shiftReport);
                    return shiftReport.start;
                })
                .observeOn(Schedulers.io())
                .map((Function<Long, CbfReport>) aLong -> {
                    CbfReport data = Report.getInstance().getCurrentCBFDoffer(aLong);
                    return data;
                })
                .observeOn(AndroidSchedulers.mainThread());

        Observer<CbfReport> observer = new Observer<CbfReport>() {
            Disposable d;

            @Override
            public void onSubscribe(Disposable d) {
                this.d = d;
            }

            @Override
            public void onNext(CbfReport cbfReport) {
                showDutyReportCBF(cbfReport);
                setBtnState(true);
            }

            @Override
            public void onError(Throwable e) {
                if (d != null && !d.isDisposed()) {
                    d.dispose();
                }
            }

            @Override
            public void onComplete() {
                if (d != null && !d.isDisposed()) {
                    d.dispose();
                }
            }
        };
        observable.subscribe(observer);
    }

    private void rxDoffer(long time, String flag) {
        setBtnState(false);
        Observable<CbfReport> observable = Observable.create((ObservableOnSubscribe<ShiftReport>) emitter -> {
            long sqlTime = Report.getInstance().getTime(time, flag);
            ShiftReport basicInfo = Report.getInstance().getBasicInfo(sqlTime);
            totalRecord = Report.getInstance().getShiftCount();
            switch (flag) {
                case "<<":
                    currentRecord = 1;
                    break;
                case "<":
                    if (currentRecord > 1)
                        --currentRecord;
                    break;
                case ">":
                    if (currentRecord < totalRecord)
                        ++currentRecord;
                    break;
                case ">>":
                    currentRecord = totalRecord;
                    break;
            }
            emitter.onNext(basicInfo);
            emitter.onComplete();
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map((Function<ShiftReport, Long>) shiftReport -> {
                    refreshBasicUI(shiftReport);
                    return shiftReport.start;
                })
                .observeOn(Schedulers.io())
                .map((Function<Long, CbfReport>) aLong -> {
                    CbfReport data = Report.getInstance().getCurrentCBFDoffer(aLong);
                    return data;
                })
                .observeOn(AndroidSchedulers.mainThread());

        Observer<CbfReport> observer = new Observer<CbfReport>() {
            Disposable d;

            @Override
            public void onSubscribe(Disposable d) {
                this.d = d;
            }

            @Override
            public void onNext(CbfReport cbfReport) {
                showDutyReportDoffer(cbfReport);
                setBtnState(true);
            }

            @Override
            public void onError(Throwable e) {
                if (d != null && !d.isDisposed()) {
                    d.dispose();
                }
            }

            @Override
            public void onComplete() {
                if (d != null && !d.isDisposed()) {
                    d.dispose();
                }
            }
        };
        observable.subscribe(observer);
    }
}